import { useStore as useAnalysisStore } from "@/store/analysis";
import { computed, ref } from "vue";
import _ from "lodash";
import { Midi } from "@tonejs/midi";
import { getMultiple } from "@/common/utils/museXmlDeal";
export default () => {
  const stateOri = {
    scale: "",
    tempo: 0,
    lyrics: [] as any[],
    beat: "" as any,
  }
  const state = ref(_.cloneDeep(stateOri));
  const tempDataOri = {
    midCount: 0, //mid循环计数
    firstChordIdx: 0, //第一个和弦
    xmlCount: 0, //xml循环计数
    lyricsIdx: -1,
    duration: 0,
  }
  const tempData = ref(_.cloneDeep(tempDataOri));
  const result = computed(() => {
    return {
      temp: state.value.tempo,
      beat: state.value.beat,
      scale: state.value.scale,
      lyrics: state.value.lyrics,
    }
  })
  const analysisStore = useAnalysisStore();
  const initState = () => {
    state.value = _.cloneDeep(stateOri);
  }
  const initTempData = () => {
    tempData.value = _.cloneDeep(tempDataOri);
  }
  const isWord = (note: any) => {
    return note.word;
  }
  const isChord = (note: any) => {
    return note.choose && note.beat;
  }
  const dealFile = async (midFile) => {
    initState();
    initTempData();
    const midRes = await Midi.fromUrl(midFile);
    const midNotes = midRes?.tracks?.[0]?.notes || [];
    state.value.beat = midRes?.header?.ppq;
    let tempo = Number(midRes?.header?.tempos?.[0]?.bpm?.toFixed(0) || "");
    state.value.tempo = ((60 / tempo) * 1000000).toFixed(0)
    // 组装xml数组
    let xmlList: any[] = [];
    analysisStore.xmlData.measures.forEach((measuresItem, measuresIdx) => {
      const multiple = getMultiple(measuresItem);
      measuresItem.forEach((noteItem, noteIdx) => {
        noteItem.multiple = multiple;
        xmlList.push(noteItem);
      })
    })
    tempData.value.firstChordIdx = xmlList.findIndex(x => isChord(x));
    // 处理mid文件数据
    xmlList.forEach((noteItem, noteIdx) => {
      if (!noteItem.isRest && !noteItem.isGrace) {
        if (noteItem.isTiedStop) {
          noteItem.midi = midNotes[tempData.value.midCount - 1].midi;
          noteItem.velocity = String(midNotes[tempData.value.midCount - 1].velocity * 127);
        } else {
          noteItem.midi = midNotes[tempData.value.midCount].midi;
          noteItem.velocity = String(midNotes[tempData.value.midCount].velocity * 127);
          tempData.value.midCount++;
        }
      }
    })
    xmlList.forEach((noteItem, noteIdx) => {
      if (isChord(noteItem)) {
        tempData.value.duration = 0;
      }
      if (noteItem.isGrace) {
        return;
      }
      // 在第一个和弦之前的文字,仅放入文字
      if (noteIdx < tempData.value.firstChordIdx) {
        if (isWord(noteItem)) {
          state.value.lyrics.push({
            word: noteItem.word,
          })
          tempData.value.lyricsIdx++;
        }
      } else {
        if (isWord(noteItem) || isChord(noteItem)) {
          let obj: any = {
            word: noteItem.word || "",
            melody: [],
          }
          noteItem.beat && (obj.beat = noteItem.beat);
          noteItem.chooseOri && (obj.chooseOri = noteItem.chooseOri);
          noteItem.choose && (obj.choose = noteItem.choose);
          state.value.lyrics.push(obj);
          tempData.value.lyricsIdx++;
        }
        if (!noteItem.isRest) {
          if (noteItem.isChord) {
            // 单字多音同时按下duration特殊处理
            tempData.value.duration = noteIdx === tempData.value.firstChordIdx ? 0 : tempData.value.duration - noteItem.duration * noteItem.multiple;
            state.value.lyrics[tempData.value.lyricsIdx].melody.push({
              Note: noteItem.midi,
              Velocity: noteItem.velocity,
              duration: tempData.value.duration,
            })
            tempData.value.duration = tempData.value.duration + noteItem.duration * noteItem.multiple;
            state.value.lyrics[tempData.value.lyricsIdx].melody.push({
              Note: noteItem.midi,
              Velocity: "0",
              duration: tempData.value.duration,
            })
          } else if (noteItem.isTiedStop) {
            // 单字连音duration特殊处理
            // 当是和弦时,不延长时间,视为休止符
            if (isChord(noteItem)) {
              state.value.lyrics[tempData.value.lyricsIdx].melody.push({
                Note: "0",
                Velocity: xmlList?.[noteIdx - 1]?.velocity || "0",
                duration: tempData.value.duration,
              })
              tempData.value.duration = tempData.value.duration + noteItem.duration * noteItem.multiple;
              state.value.lyrics[tempData.value.lyricsIdx].melody.push({
                Note: "0",
                Velocity: "0",
                duration: tempData.value.duration,
              })
            } else {
              //否则,延长连音起始note的duration  
              tempData.value.duration = tempData.value.duration + noteItem.duration * noteItem.multiple;
              state.value.lyrics[tempData.value.lyricsIdx].melody[state.value.lyrics[tempData.value.lyricsIdx].melody.length - 1].duration = tempData.value.duration;
            }
          } else {
            state.value.lyrics[tempData.value.lyricsIdx].melody.push({
              Note: noteItem.midi,
              Velocity: noteItem.velocity,
              duration: tempData.value.duration,
            })
            tempData.value.duration = tempData.value.duration + noteItem.duration * noteItem.multiple;
            state.value.lyrics[tempData.value.lyricsIdx].melody.push({
              Note: noteItem.midi,
              Velocity: "0",
              duration: tempData.value.duration,
            })
          }
        } else {
          if (isChord(noteItem)) {
            // 休止符处理
            state.value.lyrics[tempData.value.lyricsIdx].melody.push({
              Note: "0",
              Velocity: xmlList?.[noteIdx - 1]?.velocity || "0",
              duration: tempData.value.duration,
            })
            tempData.value.duration = tempData.value.duration + noteItem.duration * noteItem.multiple;
            state.value.lyrics[tempData.value.lyricsIdx].melody.push({
              Note: "0",
              Velocity: "0",
              duration: tempData.value.duration,
            })
          } else {
            // 无和弦休止符特殊处理
            tempData.value.duration = tempData.value.duration + noteItem.duration * noteItem.multiple;
            state.value.lyrics[tempData.value.lyricsIdx].melody[state.value.lyrics[tempData.value.lyricsIdx].melody.length - 1].duration = tempData.value.duration;
          }
        }
      }
    })
    analysisStore.setResult({
      temp: result.value.temp,
      beat: result.value.beat,
      lyrics: result.value.lyrics,
    })
    return true;
  }
  return {
    dealFile,
    state,
    result,
  }
}